package api

import (
	"encoding/json"
	"exam12_23/internal/api/request"
	"exam12_23/internal/models/dao"
	"exam12_23/internal/models/service"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"net/http"
	"strconv"
)

type Node struct {
	conn *websocket.Conn
	data chan []byte
}

var clientMap = make(map[int]*Node)

func Chat(c *gin.Context) {

	value, _ := strconv.Atoi(c.Query("readId"))

	upgrader := websocket.Upgrader{CheckOrigin: func(r *http.Request) bool {
		return true
	}}

	upgrade, err := upgrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		return
	}

	node := &Node{
		conn: upgrade,
		data: make(chan []byte, 1024),
	}

	clientMap[value] = node

	go SendMessage(node)
	go ReadMessage(node)

}

func SendMessage(node *Node) {
	for {
		select {
		case data := <-node.data:
			err := node.conn.WriteMessage(websocket.TextMessage, data)
			if err != nil {
				node.conn.Close()
				return
			}
		}
	}
}

func ReadMessage(node *Node) {
	for {
		_, i, err := node.conn.ReadMessage()
		if err != nil {
			node.conn.Close()
			return
		}
		message := dao.Message{}
		err = json.Unmarshal(i, &message)
		if !service.CreateChat(&message) {
			node.conn.Close()
			return
		}
		if err != nil {
			node.conn.Close()
			return
		}
		n := clientMap[message.SendId]
		n.data <- i
	}
}

func BeginChat(c *gin.Context) {
	value, _ := strconv.Atoi(c.Query("readId"))

	values, _ := c.Get("userId")
	userId, _ := strconv.Atoi(values.(string))

	friend := service.FindFriend(userId, value)

	if friend != "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": friend,
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "可以进行聊天",
	})

}

func ListMessage(c *gin.Context) {
	var jsons *request.ListMessage
	if err := c.ShouldBindJSON(&jsons); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	values, _ := c.Get("userId")
	userId, _ := strconv.Atoi(values.(string))

	message := service.ListMessage(userId, jsons.FriendId)
	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "历史记录拉取成功",
		"data":    message,
	})

}

func UpdateMassage(c *gin.Context) {
	var jsons *request.ListMessage
	if err := c.ShouldBindJSON(&jsons); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	values, _ := c.Get("userId")
	userId, _ := strconv.Atoi(values.(string))

	service.UpdateMessage(userId, jsons.FriendId)

	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "消息标记成功",
	})

}
